#include "AsyncPlcControl.h"
#include "utils\Logger.h"
AsyncPlcControl::AsyncPlcControl() {
	plcControl = nullptr;
	hasConnect = false;
	timer = nullptr;
	failCount = 0;
}

AsyncPlcControl::~AsyncPlcControl() {
	if (plcControl) {
		plcControl->ControlRejectBelt(DiscardBeltState::DiscardPause);
		plcControl = nullptr;
	}
	hasConnect = false;
	if (timer) {
		timer->stop();
		delete timer;
	}
	LInfo("~AsyncPlcControl");
}

bool AsyncPlcControl::HasConnected() {
	LInfo("HasConnected");
	bool ret;
	variableMtx.lock();
	ret = hasConnect; 
	variableMtx.unlock();
	return ret;
}

void AsyncPlcControl::onInit() {
	LInfo("onInit");
	if (plcControl == nullptr) {
		plcControl = std::make_shared<PlcControl>();
		plcControl->SetComNo(comNo);
		timer =  new QTimer();
		connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate()));
	}
	bool ret = plcControl->Init();
	if (ret) {
		//short value[7] = { -1,-1, -1, -1, -1, -1, -1 };
		//ret = plcControl->GetSignalData(0x8007, value);
		ret = plcMonitor();
		if(ret)
			timer->start(PLCKEEPALIVETIME);
	}
	else {
		plcControl = nullptr;
		if (timer) {
			timer->stop();
			delete timer;
		}
	}
	emit initComplete(ret);
}

void AsyncPlcControl::SetComNo(std::string _com) {
	LInfo("SetComNo");
	comNo = _com;
}


void AsyncPlcControl::onReConnection() {
	LInfo("onConnect");
	bool ret = plcControl->ReConnection();
	emit reConnectComplete(ret);
	variableMtx.lock();
	hasConnect = ret;
	variableMtx.unlock();
}


void AsyncPlcControl::onSendNGSignal() {
	LInfo("onSendNGSignal");
	if (plcControl) {
		bool ret = plcControl->SendNGSignal();
		emit SendNGSignalComplete(ret);
	}
}

void AsyncPlcControl::onSendOKSignal() {
	LInfo("onSendOKSignal");
	if (plcControl) {
		bool ret = plcControl->SendOKSignal();
		emit SendOKSignalComplete(ret);
	}
}

void AsyncPlcControl::onZeroSignals() {
	LInfo("onZeroSignals");
	if (plcControl) {
		bool ret = plcControl->ZeroSignals();
		emit ZeroSignalsComplete(ret);
	}
}

void AsyncPlcControl::onSendResetSignal(int sigNo) {
	LInfo("onSendResetSignal");
	if (plcControl) {
		bool ret = plcControl->ResetSignal(sigNo);
	}
	//emit ZeroSignalsComplete(ret);
}
void AsyncPlcControl::onSendDisableSignal(int sigNo, bool State) {
	LInfo("onSendDisableSignal");
	if (plcControl) {
		bool ret = false;
		if (State) {
			plcControl->DisableSignal(sigNo, 1);
		}
		else {
			plcControl->DisableSignal(sigNo, 0);
		}
	}
	//emit ZeroSignalsComplete(ret);
}

void AsyncPlcControl::onControlRejectBelt(int State) {
	LInfo("onControlRejectBelt");
	if (plcControl) {
		bool ret = plcControl->ControlRejectBelt(DiscardBeltState(State));
		emit ControlRejectBeltComplete(ret);
	}
}

void AsyncPlcControl::onGetSignalData(int addr) {
	LInfo("onGetSignalData");
	short value[7] = { -1,-1, -1, -1, -1, -1, -1 };
	if (plcControl) {
		bool ret = plcControl->GetSignalData(addr, value);
		variableMtx.lock();
		hasConnect = ret;
		variableMtx.unlock();
		std::vector<short> data(value, value + 7);
		emit GetSignalDataComplete(ret, data);
	}
}

void AsyncPlcControl::timerUpdate() {
	if (plcControl) {
		bool ret = plcMonitor();
		if (ret) {
			failCount = 0;
		}
		else {
			failCount++;
			if (failCount > 3) {
				emit connectInterrupt();
				failCount = 0;
				timer->stop();
			}
		}
	}
}

bool AsyncPlcControl::plcMonitor() {
	LInfo("plcMonitor GetSignalData");
	short value[7] = { -1,-1, -1, -1, -1, -1, -1 };
	bool ret = plcControl->GetSignalData(0x8007, value);
	variableMtx.lock();
	hasConnect = ret;
	variableMtx.unlock();
	std::vector<short> data(value, value + 7);
	emit GetSignalDataComplete(ret, data);
	return ret;
}


